home *** CD-ROM | disk | FTP | other *** search
/ Languguage OS 2 / Languguage OS II Version 10-94 (Knowledge Media)(1994).ISO / gnu / gnuchess.lha / Xchess / window.c < prev    next >
C/C++ Source or Header  |  1990-05-13  |  26KB  |  954 lines

  1. /* This file contains code for X-CHESS.
  2.    Copyright (C) 1986-1990 Free Software Foundation, Inc.
  3.  
  4. This file is part of X-CHESS.
  5.  
  6. X-CHESS is distributed in the hope that it will be useful,
  7. but WITHOUT ANY WARRANTY.  No author or distributor
  8. accepts responsibility to anyone for the consequences of using it
  9. or for whether it serves any particular purpose or works at all,
  10. unless he says so in writing.  Refer to the X-CHESS General Public
  11. License for full details.
  12.  
  13. Everyone is granted permission to copy, modify and redistribute
  14. X-CHESS, but only under the conditions described in the
  15. X-CHESS General Public License.   A copy of this license is
  16. supposed to have been given to you along with X-CHESS so you
  17. can know your rights and responsibilities.  It should be in a
  18. file named COPYING.  Among other things, the copyright notice
  19. and this notice must be preserved on all copies.  */
  20.  
  21.  
  22. /* RCS Info: $Revision: 1.5 $ on $Date: 86/11/26 12:11:15 $
  23.  *           $Source: /users/faustus/xchess/RCS/window.c,v $
  24.  * Copyright (c) 1986-1990 Wayne A. Christopher, U. C. Berkeley CAD Group
  25.  *    Permission is granted to do anything with this code except sell it
  26.  *    or remove this message.
  27.  *
  28.  * Deal with the two (or one) windows.
  29.  */
  30.  
  31. #include "xchess.h"
  32. #include <X11/Xutil.h>
  33. #include <sys/time.h>
  34.  
  35. #include "pawn.bitmap"
  36. #include "rook.bitmap"
  37. #include "knight.bitmap"
  38. #include "bishop.bitmap"
  39. #include "queen.bitmap"
  40. #include "king.bitmap"
  41.  
  42. #include "pawn_outline.bitmap"
  43. #include "rook_outline.bitmap"
  44. #include "knight_outline.bitmap"
  45. #include "bishop_outline.bitmap"
  46. #include "queen_outline.bitmap"
  47. #include "king_outline.bitmap"
  48.  
  49. #include "pawn_mask.bitmap"
  50. #include "rook_mask.bitmap"
  51. #include "knight_mask.bitmap"
  52. #include "bishop_mask.bitmap"
  53. #include "queen_mask.bitmap"
  54. #include "king_mask.bitmap"
  55.  
  56. #include "shade.bitmap"
  57.  
  58. #include "xchess.cur"
  59. #include "xchess_mask.cur"
  60.  
  61. #include "xchess.icon"
  62.  
  63. windata *win1, *win2;
  64. bool win_flashmove = false;
  65.  
  66. static bool setup();
  67. static void service(), drawgrid(), icon_refresh();
  68.  
  69. bool
  70. win_setup(disp1, disp2)
  71.     char *disp1, *disp2;
  72. {
  73.     win1 = alloc(windata);
  74.     if (!oneboard)
  75.         win2 = alloc(windata);
  76.  
  77.     if (!setup(disp1, win1) || (!oneboard && !setup(disp2, win2)))
  78.         return (false);
  79.  
  80.     if (blackflag) {
  81.         win1->color = BLACK;
  82.         win1->flipped = true;
  83.     } else
  84.         win1->color = WHITE;
  85.     win_drawboard(win1);
  86.  
  87.     if (!oneboard) {
  88.         win2->color = BLACK;
  89.         win2->flipped = true;
  90.         win_drawboard(win2);
  91.     }
  92.     
  93.     return(true);
  94. }
  95.  
  96. /* Draw the chess board... */
  97.  
  98. void
  99. win_drawboard(win)
  100.     windata *win;
  101. {
  102.     int i, j;
  103.  
  104.     drawgrid(win);
  105.  
  106.     /* Now toss on the squares... */
  107.     for (i = 0; i < SIZE; i++)
  108.         for (j = 0; j < SIZE; j++)
  109.             win_erasepiece(j, i, win->color);
  110.  
  111.     return;
  112. }
  113.  
  114. /* Draw one piece. */
  115.  
  116. void
  117. win_drawpiece(p, y, x, wnum)
  118.     piece *p;
  119.     int y, x;
  120.     color wnum;
  121. {
  122.     char *bits, *maskbits, *outline;
  123.     windata *win;
  124.     char buf[BSIZE];
  125.     XImage *tmpImage;
  126.     Pixmap tmpPM, maskPM;
  127.     XGCValues gc;
  128.  
  129.     if (oneboard || (wnum == win1->color))
  130.     win = win1;
  131.     else
  132.     win = win2;
  133.  
  134.     if (win->flipped) {
  135.     y = SIZE - y - 1;
  136.     x = SIZE - x - 1;
  137.     }
  138.  
  139.     /*
  140.       if (debug)
  141.       fprintf(stderr, "draw a %s at (%d, %d) on board %d\n",
  142.       piecenames[(int) p->type], y, x, wnum);
  143.       */
  144.  
  145.     if ((x < 0) || (x > 7) || (y < 0) || (y > 7)) exit(1);
  146.  
  147.     switch (p->type) {
  148.     case PAWN:
  149.     bits = pawn_bits;
  150.     maskbits = pawn_mask_bits;
  151.     outline = pawn_outline_bits;
  152.     break;
  153.  
  154.     case ROOK:
  155.     bits = rook_bits;
  156.     maskbits = rook_mask_bits;
  157.     outline = rook_outline_bits;
  158.     break;
  159.  
  160.     case KNIGHT:
  161.     bits = knight_bits;
  162.     maskbits = knight_mask_bits;
  163.     outline = knight_outline_bits;
  164.     break;
  165.  
  166.     case BISHOP:
  167.     bits = bishop_bits;
  168.     maskbits = bishop_mask_bits;
  169.     outline = bishop_outline_bits;
  170.     break;
  171.  
  172.     case QUEEN:
  173.     bits = queen_bits;
  174.     maskbits = queen_mask_bits;
  175.     outline = queen_outline_bits;
  176.     break;
  177.  
  178.     case KING:
  179.     bits = king_bits;
  180.     maskbits = king_mask_bits;
  181.     outline = king_outline_bits;
  182.     break;
  183.  
  184.     default:
  185.     fprintf(stderr,
  186.         "Internal Error: win_drawpiece: bad piece type %d\n",
  187.         p->type);
  188.     }
  189.  
  190.     /* There are two things we can do... If this is a black and white
  191.      * display, we have to shade the square and use an outline if the piece
  192.      * is white.  We also have to use a mask...  Since we don't want
  193.      * to use up too many bitmaps, create the mask bitmap, put the bits,
  194.      * and then destroy it.
  195.      */
  196.     if (win->bnw && (p->color == WHITE))
  197.     bits = outline;
  198.     if (win->bnw && !iswhite(win, x, y)) {
  199.     XSetState(win->display, DefaultGC(win->display, 0),
  200.           BlackPixel(win->display, 0),
  201.           WhitePixel(win->display, 0), GXcopy, AllPlanes);
  202.     
  203.     tmpPM = XCreateBitmapFromData(win->display, win->boardwin,
  204.                 shade_bits, SQUARE_WIDTH, SQUARE_HEIGHT);
  205.  
  206.     XCopyPlane(win->display, tmpPM, win->boardwin, DefaultGC(win->display, 0),
  207.            0, 0, SQUARE_WIDTH, SQUARE_HEIGHT,
  208.            x * (SQUARE_WIDTH + BORDER_WIDTH),
  209.            y * (SQUARE_HEIGHT + BORDER_WIDTH), 1);
  210.  
  211.     XFreePixmap(win->display, tmpPM);
  212.     
  213.     XSetFunction(win->display, DefaultGC(win->display, 0),
  214.              GXandInverted);
  215.     maskPM = XCreateBitmapFromData(win->display, win->boardwin,
  216.                       maskbits, SQUARE_WIDTH, SQUARE_HEIGHT);
  217.     XCopyPlane(win->display, maskPM, win->boardwin, DefaultGC(win->display, 0),
  218.            0, 0, SQUARE_WIDTH, SQUARE_HEIGHT,
  219.            x * (SQUARE_WIDTH + BORDER_WIDTH),
  220.            y * (SQUARE_HEIGHT + BORDER_WIDTH), 1);
  221.     XFreePixmap(win->display, maskPM);
  222.  
  223.     XSetFunction(win->display, DefaultGC(win->display, 0),
  224.              GXor);
  225.     tmpPM = XCreateBitmapFromData(win->display, win->boardwin,
  226.                 bits, SQUARE_WIDTH, SQUARE_HEIGHT);
  227.     XCopyPlane(win->display, tmpPM, win->boardwin, DefaultGC(win->display, 0),
  228.            0, 0, SQUARE_WIDTH, SQUARE_HEIGHT,
  229.            x * (SQUARE_WIDTH + BORDER_WIDTH),
  230.            y * (SQUARE_HEIGHT + BORDER_WIDTH), 1);
  231.     XFreePixmap(win->display, tmpPM);
  232.  
  233.     XSetFunction(win->display, DefaultGC(win->display, 0), GXcopy);
  234.  
  235.     } else if (win->bnw){
  236.     XSetState(win->display, DefaultGC(win->display, 0),
  237.           BlackPixel(win->display, 0),
  238.           WhitePixel(win->display, 0), GXcopy, AllPlanes);
  239.  
  240.     tmpPM = XCreateBitmapFromData(win->display, win->boardwin,
  241.                 bits, SQUARE_WIDTH, SQUARE_HEIGHT);
  242.     XCopyPlane(win->display, tmpPM, win->boardwin, DefaultGC(win->display, 0),
  243.            0, 0, SQUARE_WIDTH, SQUARE_HEIGHT,
  244.            x * (SQUARE_WIDTH + BORDER_WIDTH),
  245.            y * (SQUARE_HEIGHT + BORDER_WIDTH), 1);
  246.     XFreePixmap(win->display, tmpPM);
  247.     } else {
  248.     XSetState(win->display, DefaultGC(win->display, 0),
  249.          ((p->color == WHITE) ? win->whitepiece.pixel :
  250.                       win->blackpiece.pixel),
  251.           (iswhite(win, x, y) ? win->whitesquare.pixel :
  252.                        win->blacksquare.pixel),
  253.           GXcopy, AllPlanes);
  254.     tmpPM = XCreateBitmapFromData(win->display, win->boardwin,
  255.                 bits, SQUARE_WIDTH, SQUARE_HEIGHT);
  256.     XCopyPlane(win->display, tmpPM, win->boardwin, DefaultGC(win->display, 0),
  257.            0, 0, SQUARE_WIDTH, SQUARE_HEIGHT,
  258.            x * (SQUARE_WIDTH + BORDER_WIDTH),
  259.            y * (SQUARE_HEIGHT + BORDER_WIDTH), 1);
  260.     XFreePixmap(win->display, tmpPM);
  261.     }
  262.  
  263.     if (!record_english) {
  264.     gc.foreground = win->textcolor.pixel;
  265.     if (iswhite(win, x, y) || win->bnw)
  266.         gc.background = win->whitesquare.pixel;
  267.     else
  268.         gc.background = win->blacksquare.pixel;
  269.  
  270.     gc.font = win->small->fid;
  271.         
  272.     XChangeGC(win->display, DefaultGC(win->display, 0),
  273.           GCForeground | GCBackground | GCFont, &gc);
  274.         
  275.     if (!x) {
  276.         sprintf(buf, " %d", SIZE - y);
  277.         XDrawImageString(win->display, win->boardwin,
  278.                  DefaultGC(win->display, 0),
  279.                  1, (y + 1) * (SQUARE_HEIGHT + 
  280.                        BORDER_WIDTH) - BORDER_WIDTH + 
  281.                  win->small->max_bounds.ascent - 1, buf, 2);
  282.     }
  283.     if (y == SIZE - 1) {
  284.         sprintf(buf, "%c", 'A' + x);
  285.         XDrawImageString(win->display, win->boardwin,
  286.                  DefaultGC(win->display, 0),
  287.                  x * (SQUARE_WIDTH + BORDER_WIDTH) + 1,
  288.                  SIZE * (SQUARE_HEIGHT + BORDER_WIDTH) - BORDER_WIDTH + 
  289.                  win->small->max_bounds.ascent - 1, buf, 1);
  290.     }
  291.     }
  292.     return;
  293. }
  294.  
  295. void
  296. win_erasepiece(y, x, wnum)
  297.     int y, x;
  298.     color wnum;
  299. {
  300.     windata *win;
  301.     char buf[BSIZE];
  302.     XGCValues gc;
  303.     Pixmap tmpPM;
  304.     
  305.     if (oneboard || (wnum == win1->color))
  306.     win = win1;
  307.     else
  308.     win = win2;
  309.         
  310.     if (win->flipped) {
  311.     y = SIZE - y - 1;
  312.     x = SIZE - x - 1;
  313.     }
  314.  
  315.     /*
  316.       if (debug)
  317.       fprintf(stderr, "erase square (%d, %d) on board %d\n", y, x,
  318.       wnum);
  319.       */
  320.  
  321.     if ((x < 0) || (x > 7) || (y < 0) || (y > 7)) exit(1);
  322.  
  323.     if (win->bnw && !iswhite(win, x, y)) {
  324.     XSetState(win->display, DefaultGC(win->display, 0),
  325.           BlackPixel(win->display, 0),
  326.           WhitePixel(win->display, 0), GXcopy, AllPlanes);
  327.     tmpPM = XCreateBitmapFromData(win->display, win->boardwin,
  328.                 shade_bits, SQUARE_WIDTH, SQUARE_HEIGHT);
  329.  
  330.     XCopyPlane(win->display, tmpPM, win->boardwin, DefaultGC(win->display, 0),
  331.            0, 0, SQUARE_WIDTH, SQUARE_HEIGHT,
  332.            x * (SQUARE_WIDTH + BORDER_WIDTH),
  333.            y * (SQUARE_HEIGHT + BORDER_WIDTH), 1);
  334.  
  335.     XFreePixmap(win->display, tmpPM);
  336.     } else {
  337.     XSetFillStyle(win->display, DefaultGC(win->display, 0),
  338.               FillSolid);
  339.     XSetForeground(win->display, DefaultGC(win->display, 0),
  340.                iswhite(win, x, y) ? win->whitesquare.pixel :
  341.                win->blacksquare.pixel);
  342.     XFillRectangle(win->display, win->boardwin,
  343.                DefaultGC(win->display, 0),
  344.                x * (SQUARE_WIDTH + BORDER_WIDTH),
  345.                y * (SQUARE_HEIGHT + BORDER_WIDTH),
  346.                SQUARE_WIDTH, SQUARE_HEIGHT);
  347.     }
  348.  
  349.     if (!record_english) {
  350.     gc.foreground = win->textcolor.pixel;
  351.     if (iswhite(win, x, y) || win->bnw)
  352.         gc.background = win->whitesquare.pixel;
  353.     else
  354.         gc.background = win->blacksquare.pixel;
  355.  
  356.     gc.font = win->small->fid;
  357.         
  358.     XChangeGC(win->display, DefaultGC(win->display, 0),
  359.           GCForeground | GCBackground | GCFont, &gc);
  360.         
  361.     if (!x) {
  362.         sprintf(buf, " %d", SIZE - y);
  363.         XDrawImageString(win->display, win->boardwin,
  364.                  DefaultGC(win->display, 0),
  365.                  1, (y + 1) * (SQUARE_HEIGHT + 
  366.                        BORDER_WIDTH) - BORDER_WIDTH + 
  367.                  win->small->max_bounds.ascent - 1, buf, 2);
  368.     }
  369.     if (y == SIZE - 1) {
  370.         sprintf(buf, "%c", 'A' + x);
  371.         XDrawImageString(win->display, win->boardwin,
  372.                  DefaultGC(win->display, 0),
  373.                  x * (SQUARE_WIDTH + BORDER_WIDTH) + 1,
  374.                  SIZE * (SQUARE_HEIGHT + BORDER_WIDTH) - BORDER_WIDTH + 
  375.                  win->small->max_bounds.ascent - 1, buf, 1);
  376.     }
  377.     }
  378.     
  379.  
  380.     return;
  381. }
  382.  
  383. void
  384. win_flash(m, wnum)
  385.     move *m;
  386.     color wnum;
  387. {
  388.     windata *win;
  389.     int sx, sy, ex, ey, i;
  390.  
  391.     if (oneboard || (wnum == win1->color))
  392.         win = win1;
  393.     else
  394.         win = win2;
  395.         
  396.     if (win->flipped) {
  397.         sx = SIZE - m->fromx - 1;
  398.         sy = SIZE - m->fromy - 1;
  399.         ex = SIZE - m->tox - 1;
  400.         ey = SIZE - m->toy - 1;
  401.     } else {
  402.         sx = m->fromx;
  403.         sy = m->fromy;
  404.         ex = m->tox;
  405.         ey = m->toy;
  406.     }
  407.     sx = sx * (SQUARE_WIDTH + BORDER_WIDTH) + SQUARE_WIDTH / 2;
  408.     sy = sy * (SQUARE_HEIGHT + BORDER_WIDTH) + SQUARE_HEIGHT / 2;
  409.     ex = ex * (SQUARE_WIDTH + BORDER_WIDTH) + SQUARE_WIDTH / 2;
  410.     ey = ey * (SQUARE_HEIGHT + BORDER_WIDTH) + SQUARE_HEIGHT / 2;
  411.  
  412.     XSetFunction(win->display, DefaultGC(win->display, 0), GXinvert);
  413.     XSetLineAttributes(win->display, DefaultGC(win->display, 0),
  414.         0, LineSolid, 0, 0);
  415.     for (i = 0; i < num_flashes * 2; i++) {
  416.         XDrawLine(win->display,win->boardwin,
  417.               DefaultGC(win->display, 0),
  418.               sx, sy, ex, ey);
  419.     }
  420.     
  421.     XSetFunction(win->display, DefaultGC(win->display, 0), GXcopy);
  422.     return;
  423. }
  424.  
  425. /* Handle input from the players. */
  426.  
  427. void
  428. win_process(quick)
  429.     bool quick;
  430. {
  431.     int i, rfd = 0, wfd = 0, xfd = 0;
  432.     struct timeval timeout;
  433.  
  434.     timeout.tv_sec = 0;
  435.     timeout.tv_usec = (quick ? 0 : 500000);
  436.  
  437.     if (XPending(win1->display))
  438.         service(win1);
  439.     if (!oneboard) {
  440.         if (XPending(win1->display))
  441.         service(win2);
  442.     }
  443.  
  444.     if (oneboard)
  445.         rfd = 1 << win1->display->fd;
  446.     else
  447.         rfd = (1 << win1->display->fd) | (1 << win2->display->fd);
  448.     if (!(i = select(32, &rfd, &wfd, &xfd, &timeout)))
  449.         return;
  450.     if (i == -1) {
  451.         perror("select");
  452.         exit(1);
  453.     }
  454.     if (rfd & (1 << win1->display->fd))
  455.         service(win1);
  456.     if (!oneboard && (rfd & (1 << win2->display->fd)))
  457.         service(win2);
  458.  
  459.     return;
  460. }
  461.  
  462. static void
  463. service(win)
  464.     windata *win;
  465. {
  466.     XEvent ev;
  467.  
  468.     while(XPending(win->display)) {
  469.         XNextEvent(win->display, &ev);
  470.         if (TxtFilter(win->display, &ev))
  471.             continue;
  472.  
  473.         if (ev.xany.window == win->boardwin) {
  474.             switch (ev.type) {
  475.                 case ButtonPress:
  476.                 button_pressed(&ev, win);
  477.                 break;
  478.  
  479.                 case ButtonRelease:
  480.                 button_released(&ev, win);
  481.                 break;
  482.  
  483.                 case Expose:
  484.                 /* Redraw... */
  485.                 win_redraw(win, &ev);
  486.                 break;
  487.  
  488.                 case 0:
  489.                 case NoExpose:
  490.                 break;
  491.                 default:
  492.                 fprintf(stderr, "Bad event type %d\n", ev.type);
  493.                 exit(1);
  494.             }
  495.         } else if (ev.xany.window == win->wclockwin) {
  496.             switch (ev.type) {
  497.                 case Expose:
  498.                 clock_draw(win, WHITE);
  499.                 break;
  500.  
  501.                 case 0:
  502.                 case NoExpose:
  503.                 break;
  504.                 default:
  505.                 fprintf(stderr, "Bad event type %d\n", ev.type);
  506.                 exit(1);
  507.             }
  508.         } else if (ev.xany.window == win->bclockwin) {
  509.             switch (ev.type) {
  510.                 case Expose:
  511.                 clock_draw(win, BLACK);
  512.                 break;
  513.  
  514.                 case 0:
  515.                 case NoExpose:
  516.                 break;
  517.                 default:
  518.                 fprintf(stderr, "Bad event type %d\n", ev.type);
  519.                 exit(1);
  520.             }
  521.         } else if (ev.xany.window == win->jailwin) {
  522.             switch (ev.type) {
  523.                 case Expose:
  524.                 jail_draw(win);
  525.                 break;
  526.  
  527.                 case 0:
  528.                 case NoExpose:
  529.                 break;
  530.                 default:
  531.                 fprintf(stderr, "Bad event type %d\n", ev.type);
  532.                 exit(1);
  533.             }
  534.         } else if (ev.xany.window == win->buttonwin) {
  535.             switch (ev.type) {
  536.                 case ButtonPress:
  537.                 button_service(win, &ev);
  538.                 break;
  539.  
  540.                 case Expose:
  541.                 button_draw(win);
  542.                 break;
  543.  
  544.                 case 0:
  545.                 case NoExpose:
  546.                 break;
  547.                 default:
  548.                 fprintf(stderr, "Bad event type %d\n", ev.type);
  549.                 exit(1);
  550.             }
  551.         } else if (ev.xany.window == win->icon) {
  552.             icon_refresh(win);
  553.         } else if (ev.xany.window == win->basewin) {
  554.             message_send(win, &ev);
  555.         } else {
  556.             fprintf(stderr, "Internal Error: service: bad win\n");
  557.             fprintf(stderr, "window = %d, event = %d\n", ev.xany.window,
  558.                     ev.type);
  559.         }
  560.     }
  561.     return;
  562. }
  563.  
  564. void
  565. win_redraw(win, event)
  566.     windata *win;
  567.     XEvent *event;
  568. {
  569.     XExposeEvent *ev = &event->xexpose;
  570.     int x1, y1, x2, y2, i, j;
  571.  
  572.     drawgrid(win);
  573.     if (ev) {
  574.         x1 = ev->x / (SQUARE_WIDTH + BORDER_WIDTH);
  575.         y1 = ev->y / (SQUARE_HEIGHT + BORDER_WIDTH);
  576.         x2 = (ev->x + ev->width) / (SQUARE_WIDTH + BORDER_WIDTH);
  577.         y2 = (ev->y + ev->height) / (SQUARE_HEIGHT + BORDER_WIDTH);
  578.     } else {
  579.         x1 = 0;
  580.         y1 = 0;
  581.         x2 = SIZE - 1;
  582.         y2 = SIZE - 1;
  583.     }
  584.  
  585.     if (x1 < 0) x1 = 0;
  586.     if (y1 < 0) y1 = 0;
  587.     if (x2 < 0) x2 = 0;
  588.     if (y2 < 0) y2 = 0;
  589.     if (x1 > SIZE - 1) x1 = SIZE - 1;
  590.     if (y1 > SIZE - 1) y1 = SIZE - 1;
  591.     if (x2 > SIZE - 1) x2 = SIZE - 1;
  592.     if (y2 > SIZE - 1) y2 = SIZE - 1;
  593.  
  594.     if (win->flipped) {
  595.         y1 = SIZE - y2 - 1;
  596.         y2 = SIZE - y1 - 1;
  597.         x1 = SIZE - x2 - 1;
  598.         x2 = SIZE - x1 - 1;
  599.     }
  600.  
  601.     for (i = x1; i <= x2; i++) 
  602.         for (j = y1; j <= y2; j++) {
  603.             if (chessboard->square[j][i].color == NONE)
  604.                 win_erasepiece(j, i, WHITE);
  605.             else
  606.                 win_drawpiece(&chessboard->square[j][i], j, i,
  607.                         WHITE);
  608.             if (!oneboard) {
  609.                 if (chessboard->square[j][i].color == NONE)
  610.                     win_erasepiece(j, i, BLACK);
  611.                 else
  612.                     win_drawpiece(&chessboard->square[j][i],
  613.                             j, i, BLACK);
  614.             }
  615.         }
  616.     
  617.     return;
  618. }
  619.  
  620. static bool
  621. setup(dispname, win)
  622.     char *dispname;
  623.     windata *win;
  624. {
  625.     char buf[BSIZE], *s;
  626.     Pixmap bm, bmask;
  627.     Cursor cur;
  628.     extern char *program, *recfile;
  629.     XSizeHints xsizes;
  630.     
  631.  
  632.     if (!(win->display = XOpenDisplay(dispname)))
  633.         return (false);
  634.     
  635.  
  636.     /* Now get boolean defaults... */
  637.     if ((s = XGetDefault(win->display, program, "noisy")) && eq(s, "on"))
  638.         noisyflag = true;
  639.     if ((s = XGetDefault(win->display, program, "savemoves")) && eq(s, "on"))
  640.         saveflag = true;
  641.     if ((s = XGetDefault(win->display, program, "algebraic")) && eq(s, "on"))
  642.         record_english = false;
  643.     if ((s = XGetDefault(win->display, program, "blackandwhite")) && eq(s, "on"))
  644.         bnwflag = true;
  645.     if ((s = XGetDefault(win->display, program, "quickrestore")) && eq(s, "on"))
  646.         quickflag = true;
  647.     if ((s = XGetDefault(win->display, program, "flash")) && eq(s, "on"))
  648.         win_flashmove = true;
  649.     
  650.     /* ... numeric variables ... */
  651.     if (s = XGetDefault(win->display, program, "numflashes"))
  652.         num_flashes = atoi(s);
  653.     if (s = XGetDefault(win->display, program, "flashsize"))
  654.         flash_size = atoi(s);
  655.     
  656.     /* ... and strings. */
  657.     if (s = XGetDefault(win->display, program, "progname"))
  658.         progname = s;
  659.     if (s = XGetDefault(win->display, program, "proghost"))
  660.         proghost = s;
  661.     if (s = XGetDefault(win->display, program, "recordfile"))
  662.         recfile = s;
  663.     if (s = XGetDefault(win->display, program, "blackpiece"))
  664.         black_piece_color = s;
  665.     if (s = XGetDefault(win->display, program, "whitepiece"))
  666.         white_piece_color = s;
  667.     if (s = XGetDefault(win->display, program, "blacksquare"))
  668.         black_square_color = s;
  669.     if (s = XGetDefault(win->display, program, "whitesquare"))
  670.         white_square_color = s;
  671.     if (s = XGetDefault(win->display, program, "bordercolor"))
  672.         border_color = s;
  673.     if (s = XGetDefault(win->display, program, "textcolor"))
  674.         text_color = s;
  675.     if (s = XGetDefault(win->display, program, "textback"))
  676.         text_back = s;
  677.     if (s = XGetDefault(win->display, program, "errortext"))
  678.         error_text = s;
  679.     if (s = XGetDefault(win->display, program, "playertext"))
  680.         player_text = s;
  681.     if (s = XGetDefault(win->display, program, "cursorcolor"))
  682.         cursor_color = s;
  683.  
  684.     if ((DisplayPlanes(win->display, 0) == 1) || bnwflag)
  685.         win->bnw = true;
  686.     
  687.     /* Allocate colors... */
  688.     if (win->bnw) {
  689.         win->blackpiece.pixel = BlackPixel (win->display, 0);
  690.         win->whitepiece.pixel = WhitePixel (win->display, 0);
  691.         win->blacksquare.pixel = BlackPixel (win->display, 0);
  692.         win->whitesquare.pixel = WhitePixel (win->display, 0);
  693.         win->border.pixel = BlackPixel (win->display, 0);
  694.         win->textcolor.pixel = BlackPixel (win->display, 0);
  695.         win->textback.pixel = WhitePixel (win->display, 0);
  696.         win->playertext.pixel = BlackPixel (win->display, 0);
  697.         win->errortext.pixel = BlackPixel (win->display, 0);
  698.         win->cursorcolor.pixel = BlackPixel (win->display, 0) ;
  699.     } else {
  700.         if (!XParseColor(win->display,
  701.                  DefaultColormap(win->display, 0),
  702.                  black_piece_color, &win->blackpiece) ||  
  703.         !XParseColor(win->display,
  704.                  DefaultColormap(win->display, 0),
  705.                  white_piece_color, &win->whitepiece) ||  
  706.         !XParseColor(win->display,
  707.                  DefaultColormap(win->display, 0),
  708.                  black_square_color, &win->blacksquare) ||  
  709.         !XParseColor(win->display,
  710.                  DefaultColormap(win->display, 0),
  711.                  white_square_color, &win->whitesquare) ||  
  712.         !XParseColor(win->display,
  713.                  DefaultColormap(win->display, 0),
  714.                  border_color, &win->border) ||  
  715.         !XParseColor(win->display,
  716.                  DefaultColormap(win->display, 0),
  717.                  text_color, &win->textcolor) ||  
  718.         !XParseColor(win->display,
  719.                  DefaultColormap(win->display, 0),
  720.                  text_back, &win->textback) ||  
  721.         !XParseColor(win->display,
  722.                  DefaultColormap(win->display, 0),
  723.                  error_text, &win->errortext) ||  
  724.         !XParseColor(win->display,
  725.                  DefaultColormap(win->display, 0),
  726.                  player_text, &win->playertext) ||  
  727.         !XParseColor(win->display,
  728.                  DefaultColormap(win->display, 0),
  729.                  cursor_color, &win->cursorcolor) ||
  730.         !XAllocColor(win->display,
  731.                  DefaultColormap(win->display, 0),
  732.                  &win->blackpiece) ||  
  733.         !XAllocColor(win->display,
  734.                  DefaultColormap(win->display, 0),
  735.                  &win->whitepiece) ||  
  736.         !XAllocColor(win->display,
  737.                  DefaultColormap(win->display, 0),
  738.                  &win->blacksquare) ||  
  739.         !XAllocColor(win->display,
  740.                  DefaultColormap(win->display, 0),
  741.                  &win->whitesquare) ||   
  742.         !XAllocColor(win->display,
  743.                  DefaultColormap(win->display, 0),
  744.                  &win->border) ||  
  745.         !XAllocColor(win->display,
  746.                  DefaultColormap(win->display, 0),
  747.                  &win->textcolor) ||  
  748.         !XAllocColor(win->display,
  749.                  DefaultColormap(win->display, 0),
  750.                  &win->textback) ||  
  751.         !XAllocColor(win->display,
  752.                  DefaultColormap(win->display, 0),
  753.                  &win->errortext) ||  
  754.         !XAllocColor(win->display,
  755.                  DefaultColormap(win->display, 0),
  756.                  &win->playertext) ||  
  757.         !XAllocColor(win->display,
  758.                  DefaultColormap(win->display, 0),
  759.                  &win->cursorcolor))   
  760.         fprintf(stderr, "Can't get colors...\n");
  761.     }
  762.  
  763.     /* Get fonts... */
  764.     if ((win->small = XLoadQueryFont(win->display,SMALL_FONT)) ==
  765.         NULL)
  766.         fprintf(stderr, "Can't get small font...\n");
  767.  
  768.     if ((win->medium = XLoadQueryFont(win->display,MEDIUM_FONT))
  769.         == NULL)
  770.         fprintf(stderr, "Can't get medium font...\n");
  771.  
  772.     if ((win->large = XLoadQueryFont(win->display,LARGE_FONT)) ==
  773.         NULL)
  774.         fprintf(stderr, "Can't get large font...\n");
  775.  
  776.     
  777.     /* Create the windows... */
  778.  
  779.     win->basewin =
  780.         XCreateSimpleWindow(win->display,DefaultRootWindow(win->display),
  781.               BASE_XPOS, BASE_YPOS, 
  782.               BASE_WIDTH, BASE_HEIGHT, 0,
  783.               BlackPixel(win->display, 0),
  784.               WhitePixel(win->display, 0)); 
  785.     win->boardwin = XCreateSimpleWindow(win->display,win->basewin,
  786.                         BOARD_XPOS, BOARD_YPOS, 
  787.                         BOARD_WIDTH, BOARD_HEIGHT,
  788.                         BORDER_WIDTH,
  789.                         win->border.pixel,
  790.                         WhitePixel(win->display, 0));
  791.     win->recwin = XCreateSimpleWindow(win->display,win->basewin,
  792.                       RECORD_XPOS, RECORD_YPOS,
  793.                       RECORD_WIDTH, RECORD_HEIGHT,
  794.                       BORDER_WIDTH, win->border.pixel,
  795.                       win->textback.pixel);
  796.     win->jailwin = XCreateSimpleWindow(win->display,win->basewin,
  797.                        JAIL_XPOS, JAIL_YPOS,
  798.                        JAIL_WIDTH, JAIL_HEIGHT,
  799.                        BORDER_WIDTH,
  800.                        win->border.pixel,
  801.                        win->textback.pixel);
  802.     win->wclockwin = XCreateSimpleWindow(win->display,win->basewin,
  803.                          WCLOCK_XPOS, WCLOCK_YPOS,
  804.                          CLOCK_WIDTH, CLOCK_HEIGHT,
  805.                          BORDER_WIDTH, win->border.pixel,
  806.                          win->textback.pixel);
  807.     win->bclockwin = XCreateSimpleWindow(win->display,win->basewin,
  808.                          BCLOCK_XPOS, BCLOCK_YPOS,
  809.                          CLOCK_WIDTH, CLOCK_HEIGHT,
  810.                          BORDER_WIDTH, win->border.pixel,
  811.                          win->textback.pixel);
  812.     win->messagewin = XCreateSimpleWindow(win->display,win->basewin,
  813.                           MESS_XPOS, MESS_YPOS,
  814.                           MESS_WIDTH, MESS_HEIGHT,
  815.                           BORDER_WIDTH, win->border.pixel,
  816.                           win->textback.pixel);
  817.     win->buttonwin = XCreateSimpleWindow(win->display,win->basewin,
  818.                          BUTTON_XPOS, BUTTON_YPOS,
  819.                          BUTTON_WIDTH, BUTTON_HEIGHT,
  820.                          BORDER_WIDTH, win->border.pixel,
  821.                          win->textback.pixel);
  822.     
  823.     /* Let's define an icon... */
  824.     win->iconpixmap = XCreatePixmapFromBitmapData(win->display,
  825.                               win->basewin, icon_bits,
  826.                               icon_width, icon_height,
  827.                               win->blacksquare.pixel,
  828.                               win->whitesquare.pixel,
  829.                               1);
  830.     xsizes.flags = PSize | PMinSize | PPosition;
  831.     xsizes.min_width = BASE_WIDTH;
  832.     xsizes.min_height = BASE_HEIGHT;
  833.     xsizes.x = BASE_XPOS;
  834.     xsizes.y = BASE_YPOS;
  835.     XSetStandardProperties(win->display, win->basewin,
  836.                    program, program, win->iconpixmap,
  837.                    0, NULL, &xsizes);
  838.     
  839.     bm = XCreateBitmapFromData(win->display,
  840.                    win->basewin, xchess_bits,
  841.                    xchess_width, xchess_height);
  842.     bmask = XCreateBitmapFromData(win->display,
  843.                    win->basewin, xchess_mask_bits,
  844.                    xchess_width, xchess_height);
  845.     cur = XCreatePixmapCursor(win->display, bm, bmask,
  846.                 &win->cursorcolor,
  847.                 &WhitePixel(win->display, 0),
  848.                 xchess_x_hot, xchess_y_hot);
  849.     XFreePixmap(win->display, bm);
  850.     XFreePixmap(win->display, bmask);
  851.     
  852.     XDefineCursor(win->display,win->basewin, cur);
  853.  
  854.     XMapSubwindows(win->display,win->basewin);
  855.     XMapRaised(win->display,win->basewin);
  856.  
  857.     XSelectInput(win->display,win->basewin, KeyPressMask);
  858.     XSelectInput(win->display,win->boardwin,
  859.              ButtonPressMask | ButtonReleaseMask | ExposureMask);
  860.     XSelectInput(win->display,win->recwin,
  861.              ButtonReleaseMask | ExposureMask);
  862.     XSelectInput(win->display,win->jailwin, ExposureMask);
  863.     XSelectInput(win->display,win->wclockwin, ExposureMask);
  864.     XSelectInput(win->display,win->bclockwin, ExposureMask);
  865.     XSelectInput(win->display,win->messagewin,
  866.              ButtonReleaseMask | ExposureMask);
  867.     XSelectInput(win->display,win->buttonwin,
  868.              ButtonPressMask | ExposureMask);
  869.     
  870.     message_init(win);
  871.     record_init(win);
  872.     button_draw(win);
  873.     jail_init(win);
  874.     clock_init(win, WHITE);
  875.     clock_init(win, BLACK);
  876.     if (timeunit) {
  877.         if (timeunit > 1800)
  878.             sprintf(buf, "%d moves every %.2lg hours.\n",
  879.                 movesperunit, ((double) timeunit) / 3600);
  880.         else if (timeunit > 30)
  881.             sprintf(buf, "%d moves every %.2lg minutes.\n",
  882.                 movesperunit, ((double) timeunit) / 60);
  883.         else
  884.             sprintf(buf, "%d moves every %d seconds.\n",
  885.                 movesperunit, timeunit);
  886.         message_add(win, buf, false);
  887.     }
  888.     return (true);
  889. }
  890.  
  891. static void
  892. drawgrid(win)
  893.     windata *win;
  894. {
  895.     int i;
  896.     XGCValues gc;
  897.  
  898.     gc.function = GXcopy;
  899.     gc.plane_mask = AllPlanes;
  900.     gc.foreground = win->border.pixel;
  901.     gc.line_width = 0;
  902.     gc.line_style = LineSolid;
  903.     
  904.     XChangeGC(win->display,
  905.           DefaultGC(win->display, 0),
  906.           GCFunction | GCPlaneMask | GCForeground |
  907.           GCLineWidth | GCLineStyle, &gc);
  908.     
  909.     /* Draw the lines... horizontal, */
  910.     for (i = 1; i < SIZE; i++)
  911.         XDrawLine(win->display, win->boardwin,
  912.               DefaultGC(win->display, 0), 0,
  913.               i * (SQUARE_WIDTH + BORDER_WIDTH) -
  914.                   BORDER_WIDTH / 2,
  915.               SIZE * (SQUARE_WIDTH + BORDER_WIDTH),
  916.               i * (SQUARE_WIDTH + BORDER_WIDTH) -
  917.                   BORDER_WIDTH / 2);
  918.  
  919.     /* and vertical... */
  920.     for (i = 1; i < SIZE; i++)
  921.         XDrawLine(win->display, win->boardwin,
  922.               DefaultGC(win->display, 0),
  923.               i * (SQUARE_WIDTH + BORDER_WIDTH) -
  924.                 BORDER_WIDTH / 2, 0,
  925.               i * (SQUARE_WIDTH + BORDER_WIDTH) -
  926.                     BORDER_WIDTH / 2, 
  927.               SIZE * (SQUARE_WIDTH + BORDER_WIDTH));
  928.     return;
  929. }
  930.  
  931. void
  932. win_restart()
  933. {
  934.     win1->flipped = false;
  935.     win_redraw(win1, (XEvent *) NULL);
  936.     if (!oneboard) {
  937.         win2->flipped = true;
  938.         win_redraw(win2, (XEvent *) NULL);
  939.     }
  940.     return;
  941. }
  942.  
  943. static void
  944. icon_refresh(win)
  945.     windata *win;
  946. {
  947.     XCopyArea(win->display, win->iconpixmap, win->icon,
  948.           DefaultGC(win->display, 0),
  949.           0, 0, icon_width, icon_height, 0, 0);
  950.     return;
  951. }
  952.  
  953.  
  954.